import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios'

// API响应基础类型
export interface ApiResponse<T = any> {
  code: number
  message: string
  data: T
  success: boolean
}

// 请求配置扩展
export interface RequestConfig extends AxiosRequestConfig {
  showErrorToast?: boolean
  showSuccessToast?: boolean
}

// 错误类型
export interface ApiError {
  code: number
  message: string
  details?: any
}

// 创建axios实例
const createAxiosInstance = (): AxiosInstance => {
  const instance = axios.create({
    baseURL: import.meta.env.VITE_API_BASE_URL || '/api',
    timeout: 15000,
    headers: {
      'Content-Type': 'application/json',
    },
  })

  return instance
}

// 错误处理
const handleError = (error: AxiosError): ApiError => {
  if (error.response) {
    // 服务器响应错误
    const { status, data } = error.response
    const errorData = data as any

    return {
      code: status,
      message: errorData?.message || `请求失败 (${status})`,
      details: errorData,
    }
  } else if (error.request) {
    // 网络错误
    return {
      code: -1,
      message: '网络连接失败，请检查网络设置',
      details: error.request,
    }
  } else {
    // 其他错误
    return {
      code: -2,
      message: error.message || '未知错误',
      details: error,
    }
  }
}

// 请求拦截器
const setupRequestInterceptors = (instance: AxiosInstance) => {
  instance.interceptors.request.use(
    (config: AxiosRequestConfig) => {
      // 添加时间戳防止缓存
      if (config.method?.toUpperCase() === 'GET') {
        config.params = {
          ...config.params,
          _t: Date.now(),
        }
      }

      // 添加token (如果有)
      const token = localStorage.getItem('token')
      if (token && config.headers) {
        config.headers.Authorization = `Bearer ${token}`
      }

      return config
    },
    (error: AxiosError) => {
      return Promise.reject(handleError(error))
    }
  )
}

// 响应拦截器
const setupResponseInterceptors = (instance: AxiosInstance) => {
  instance.interceptors.response.use(
    (response: AxiosResponse) => {
      const { data, config } = response

      // 标准化响应格式
      if (data.code !== undefined) {
        // 后端返回标准格式
        if (data.code === 200 || data.success === true) {
          // 请求成功
          if ((config as RequestConfig).showSuccessToast && data.message) {
            // 可以在这里集成toast通知
            console.log('Success:', data.message)
          }
          return data
        } else {
          // 业务错误
          const error: ApiError = {
            code: data.code,
            message: data.message || '操作失败',
            details: data,
          }
          return Promise.reject(error)
        }
      } else {
        // 后端返回非标准格式，包装为标准格式
        return {
          code: 200,
          message: '操作成功',
          data: data,
          success: true,
        }
      }
    },
    (error: AxiosError) => {
      const apiError = handleError(error)

      // 处理特定错误码
      switch (apiError.code) {
        case 401:
          // 未授权，清除token并跳转登录页
          localStorage.removeItem('token')
          // 可以在这里处理跳转逻辑
          break
        case 403:
          // 权限不足
          break
        case 500:
          // 服务器错误
          break
      }

      // 显示错误提示
      if ((error.config as RequestConfig)?.showErrorToast !== false) {
        console.error('API Error:', apiError.message)
        // 可以在这里集成toast通知
      }

      return Promise.reject(apiError)
    }
  )
}

// 创建HTTP实例
const http = createAxiosInstance()
setupRequestInterceptors(http)
setupResponseInterceptors(http)

// HTTP请求方法
export const request = {
  get: <T = any>(url: string, config?: RequestConfig): Promise<ApiResponse<T>> => {
    return http.get(url, config)
  },

  post: <T = any>(url: string, data?: any, config?: RequestConfig): Promise<ApiResponse<T>> => {
    return http.post(url, data, config)
  },

  put: <T = any>(url: string, data?: any, config?: RequestConfig): Promise<ApiResponse<T>> => {
    return http.put(url, data, config)
  },

  delete: <T = any>(url: string, config?: RequestConfig): Promise<ApiResponse<T>> => {
    return http.delete(url, config)
  },

  patch: <T = any>(url: string, data?: any, config?: RequestConfig): Promise<ApiResponse<T>> => {
    return http.patch(url, data, config)
  },
}

export default http
